// HSS.Logging.LogConfiguration.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       LogConfiguration.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/04/2010
// ----------------------------------------------------------------------------
namespace HSS.Logging
{
	#region Using Directives
	using System;
	using System.IO;
	using System.Reflection;
	using HSS;
	#endregion

	#region LogConfiguration
	/// <summary>
	/// A class that represents an event log configuration
	/// </summary>
	[Serializable]
	public sealed class LogConfiguration : ILogConfiguration
	{
		#region Fields
		private static readonly object lockFolders;
		static string fileName = "logConfig.xml";
		#endregion

		#region Constructor
		/// <summary>
		/// Default Public CTOR 
		/// </summary>
		/// <remarks>Required for Serialization</remarks>
		public LogConfiguration()
		{
			this.Id = Guid.NewGuid().ToString();
			this.Name = "LogConfiguration1";
			this._logType = EventLogType.Machine;
			this._autoTruncate = false;
			this._truncateAt = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0);
			this._daysToRetain = 30;
			this._dbConnString = string.Empty;
		}
		/// <summary>
		/// Creates a new EventLogConfiguration using the parameters
		/// </summary>
		/// <param name="id">The unique Id for this Configuration</param>
		/// <param name="name">The friendly name for this Configuration</param>
		/// <param name="logType">The Type of log to write event entries to</param>
		/// <param name="autoTruncate">Indicate whether or not to auto truncate the eventlog</param>
		/// <param name="truncateAt">If AutoTruncate is true indicates the time of day in which to execute the Truncate Command</param>
		/// <param name="daysToRetain">If AutoTruncate is true indicates the number of days to retain</param>
		/// <param name="dbConnString">The Id of the Database Configuration to use</param>
		public LogConfiguration(string id, string name, EventLogType logType, bool autoTruncate, DateTime truncateAt, int daysToRetain, string dbConnString)
		{
			this.Id = id;
			this.Name = "LogConfiguration1";
			this._logType = logType;
			this._autoTruncate = autoTruncate;
			this._truncateAt = truncateAt;
			this._daysToRetain = daysToRetain;
			this._dbConnString = dbConnString;
		}
		/// <summary>
		/// Creates a new EventLogConfiguration using the EventLog passed in
		/// </summary>
		/// <param name="eventLogConfig">Pre-existing EventLogConfiguration</param>
		public LogConfiguration(LogConfiguration eventLogConfig)
		{
			this.Id = eventLogConfig.Id;
			this.Name = eventLogConfig.Name;
			this._logType = eventLogConfig.LogType;
			this._autoTruncate = eventLogConfig.AutoTruncate;
			this._truncateAt = eventLogConfig.TruncateAt;
			this._daysToRetain = eventLogConfig.DaysToRetain;
			this._dbConnString = eventLogConfig.DbConnString;
		}
		/// <summary>
		/// Static Constructor
		/// </summary>
		static LogConfiguration()
		{
			LogConfiguration.lockFolders = new object();
		}
		#endregion

		#region Properties
		/// <summary>
		/// The unique id for the data stored in this object.
		/// </summary>
		public string Id
		{
			get;
			set;
		}
		/// <summary>
		/// The friendly name for the data stored in this object.
		/// </summary>
		public string Name
		{
			get;
			set;
		}
		/// <summary>
		/// Returns a reference to the derived instance, as an Object.
		/// </summary>
		public object Data
		{
			get { return (object)this; }
			set { }
		}
		/// <summary>
		/// The Type of log to write event entries to
		/// </summary>
		public EventLogType LogType
		{
			get { return _logType; }
			set { _logType = value; }
		} EventLogType _logType;
		/// <summary>
		/// Indicate whether or not to auto truncate the eventlog
		/// </summary>
		public bool AutoTruncate
		{
			get { return _autoTruncate; }
			set { _autoTruncate = value; }
		} bool _autoTruncate;
		/// <summary>
		/// If AutoTruncate is true indicates the time of day in which to execute the Truncate Command
		/// </summary>
		public DateTime TruncateAt
		{
			get { return _truncateAt; }
			set { _truncateAt = value; }
		} DateTime _truncateAt;
		/// <summary>
		/// If AutoTruncate is true indicates the number of days to retain
		/// </summary>
		public int DaysToRetain
		{
			get { return _daysToRetain; }
			set { _daysToRetain = value; }
		} int _daysToRetain;
		/// <summary>
		/// The Id of the Database Configuration to use
		/// </summary>
		public string DbConnString
		{
			get { return _dbConnString; }
			set { _dbConnString = value; }
		} string _dbConnString;
		#endregion

		#region Methods
		/// <summary>
		/// Create a shallow copy Clone of this object
		/// </summary>
		/// <returns>Returns a shallow copy of this object</returns>
		public object Clone()
		{
			return this.MemberwiseClone();
		}
		/// <summary>
		/// The Name of the EventLog
		/// </summary>
		/// <returns>Name of the EventLog</returns>
		public override string ToString()
		{
			return this.Name;
		}
		#endregion

		#region Serialization
		/// <summary>
		/// Load an instance from persisted Xml
		/// </summary>
		/// <returns>An instance of a LogConfiguration</returns>
		public static LogConfiguration LoadInstance()
		{
			string filePath = Path.Combine(LogConfiguration.GetBinFolder(), fileName);
			if (!File.Exists(filePath))
			{
				LogConfiguration config = new LogConfiguration();
				config.SaveInstance();
				config = null;
			}
			string xml = File.ReadAllText(filePath);
			return ObjectSerialization.FromEncryptedString<LogConfiguration>(xml, typeof(LogConfiguration).FullName);
		}
		/// <summary>
		/// Persists the current instance to file
		/// </summary>
		public void SaveInstance()
		{
			string filePath = Path.Combine(LogConfiguration.GetBinFolder(), fileName);
			string xml = this.ToEncryptedString(typeof(LogConfiguration).FullName);
			File.WriteAllText(filePath, xml);
		}
		#endregion

		#region Static Methods
		/// <summary>
		/// Extract the location where the LogConfiguration is installed. AKA, AppRoot
		/// </summary>
		/// <returns>The Folder Location of the AppRoot</returns>
		public static string GetAppRoot()
		{
			if (string.IsNullOrEmpty(_appRoot))
			{
				lock (lockFolders)
				{
					if (string.IsNullOrEmpty(_appRoot))
					{
						// Get the location of the dll - Should be in the App/Bin Folder
						_binFolder = Directory.GetParent(Assembly.GetEntryAssembly().Location).FullName;
						// AppRoot = Location minus Bin
						_appRoot = Directory.GetParent(_binFolder).FullName;
					}
				}
			}
			return _appRoot;
		} static string _appRoot;
		/// <summary>
		/// Get the BIN Folder
		/// </summary>
		/// <returns>The Folder Location of the BIN</returns>
		public static string GetBinFolder()
		{
			if (string.IsNullOrEmpty(_binFolder))
			{
				lock (lockFolders)
				{
					if (string.IsNullOrEmpty(_binFolder))
					{
						// Get the location of the dll - Should be in the App/Bin Folder
						_binFolder = Directory.GetParent(Assembly.GetEntryAssembly().Location).FullName;
						// AppRoot = Location minus Bin
						_appRoot = Directory.GetParent(_binFolder).FullName;
					}
				}
			}
			return _binFolder;
		}  static string _binFolder;
		#endregion
	}
	#endregion
}